﻿using System;
using System.Drawing;
using System.Windows.Controls;
using System.Windows.Forms.Integration;
using System.Windows.Interop;

namespace Levfier
{
    /// <summary>
    /// Helper class to attach a WPF UserControl to a Win32 native main window of the host.
    /// </summary>
    /// <typeparam name="T">The type of the managed WPF Control.</typeparam>
    public class WpfControlWrapper<T> where T : UserControl, new()
    {
        /// <summary>
        /// 画面
        /// </summary>
        public T Instance { get; set; }

        /// <summary>
        /// ウィンドウハンドルのソース
        /// </summary>
        public HwndSource _hwndSource;

        /// <summary>
        /// 謎のポインタ
        /// </summary>
        public IntPtr hWnd;

        /// <summary>
        /// 画面幅
        /// </summary>
        private int _width;

        /// <summary>
        /// 画面高さ
        /// </summary>
        private int _height;

        /// <summary>
        /// フォームから画面を呼び出す際の中継
        /// </summary>
        public ElementHost ElementHost;

        /// <summary>
        /// Constructs a new instance for the specified <paramref name="width"/> and <paramref name="height"/>.
        /// </summary>
        /// <param name="width">The width of the control.</param>
        /// <param name="height">The height of the control.</param>
        public WpfControlWrapper(int width, int height)
        {
            Instance = new T();
            //System.Windows.Forms.Integration.WindowsFormsHost.EnableWindowsFormsInterop();
            this._height = height;
            this._width = width;
        }

        /// <summary>
        /// Opens and attaches the Control to the <paramref name="hWnd"/>.
        /// </summary>
        /// <param name="hWnd">The native win32 handle to the main window of the host.</param>
        public void Open(IntPtr hWnd)
        {
            this.hWnd = hWnd;

            if (null == this.ElementHost)
            {
                //画面の作成と描画のスレッドが違うとInvalidOperationが出るため対策
                Instance.Dispatcher.BeginInvoke((Action)(() =>
                {
                    Instance.Width = this._width;
                    Instance.Height = this._height;
                    this.ElementHost = new ElementHost();
                    this.ElementHost.Dock = System.Windows.Forms.DockStyle.Fill;
                    this.ElementHost.Width = this._width;
                    this.ElementHost.Height = this._height;
                    this.ElementHost.Child = Instance;
                    NativeMethods.SetParent(this.ElementHost.Handle, hWnd);
                })
                );
            }
            else
            {
                NativeMethods.SetParent(this.ElementHost.Handle, hWnd);
            }

            //HwndSourceParameters hwndParams = new HwndSourceParameters("VST.NET Wpf Editor");
            //hwndParams.ParentWindow = hWnd;
            //hwndParams.WindowStyle = 0x10000000 | 0x40000000; // WS_VISIBLE|WS_CHILD

            //_hwndSource = new HwndSource(hwndParams);
            //_hwndSource.AddHook(this.messageHook);


            //_hwndSource.RootVisual = Instance;

            //HwndSource hwndSource = HwndSource.FromHwnd(hWnd);
            //Window window = hwndSource.RootVisual as Window;

            //ElementHost.EnableModelessKeyboardInterop(window);
        }

        /// <summary>
        /// Returns the bounding rectangle of the Control.
        /// </summary>
        /// <param name="rect">Receives the bounding rectangle.</param>
        /// <remarks>The same size as in design-time.</remarks>
        public void GetBounds(out Rectangle rect)
        {
            rect = new Rectangle(0, 0, _width, _height);
        }

        /// <summary>
        /// Closes and destroys the Control.
        /// </summary>
        public void Close()
        {
            if (_hwndSource != null)
            {
                HwndSourceParameters hwndParams = new HwndSourceParameters("VST.NET Wpf Editor");
                hwndParams.ParentWindow = hWnd;
                hwndParams.Height = _height;
                hwndParams.Width = _width;
                hwndParams.WindowStyle = 0x00000000 | 0x40000000; // WS_VISIBLE|WS_CHILD

                _hwndSource = new HwndSource(hwndParams);
                //_hwndSource.Dispose();
                //_hwndSource = null;
            }

            //_instance = null;
        }
    }
}
